//
//  RHMQTTManage.m
//  RuiHeAppApp
//
//  Created by Jun on 2023/8/11.
//

#import "RHMQTTManage.h"
#import "RHMQDevModel.h"
#import <MQTTClient/MQTTClient.h>
#import "RHMQMsgModel.h"

@interface RHMQTTManage()<MQTTSessionDelegate>

@property (nonatomic ,strong) MQTTCFSocketTransport *transport;

@property (nonatomic ,strong) MQTTCFSocketTransport *otherTransport;

@property (nonatomic ,strong) MQTTSession *mySession;

@property (nonatomic ,strong) MQTTSession *otherSession;

@property (nonatomic ,assign) BOOL isConnect;
//用户
@property (nonatomic ,copy) NSString *mqtt_username;
//密码
@property (nonatomic ,copy) NSString *mqtt_password;

@property (nonatomic ,strong) NSMutableArray *sessionArray;

@property (nonatomic ,assign) BOOL isSend;

@property (nonatomic ,assign) BOOL beginConnect;

@end

@implementation RHMQTTManage

+ (RHMQTTManage *)shareMQTTManage{
    static id sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}


- (instancetype)init{
    self = [super init];
    if (self) {
        self.transport = [[MQTTCFSocketTransport alloc] init];
        self.otherTransport = [[MQTTCFSocketTransport alloc] init];
        self.mySession = [[MQTTSession alloc] init];
        self.otherSession = [[MQTTSession alloc] init];
        self.sessionArray = [NSMutableArray array];
        
    }
    return self;
}


- (void)setMqtt_host:(NSString *)mqtt_host{
    _mqtt_host = mqtt_host;
    self.transport.host = _mqtt_host;
    self.otherTransport.host = _mqtt_host;
}

- (void)setMqtt_port:(UInt32)mqtt_port{
    _mqtt_port = mqtt_port;
    self.transport.port = _mqtt_port;
    self.otherTransport.port = _mqtt_port;
}

//连接--
- (void)contentMqtt:(NSString *)name password:(NSString *)password{
    if(!name||!password) return;
    self.mqtt_username = name;
    self.mqtt_password = password;
    
    //[self.mySession setUserName:self.mqtt_username];
    //[self.mySession setPassword:self.mqtt_password];
    //接收离线消息级别
    [self.mySession setWillQoS:MQTTQosLevelExactlyOnce];
    [self.mySession setClientId:@"Jun123456"];
    self.mySession.transport = self.transport;
    [self.mySession setDelegate:self];
    [self.mySession connectAndWaitTimeout:1];
    
    
    [self.otherSession setWillQoS:MQTTQosLevelExactlyOnce];
    [self.otherSession setClientId:@"Jun123456789"];
    self.otherSession.transport = self.otherTransport;
    [self.otherSession setDelegate:self];
    [self.otherSession connectAndWaitTimeout:1];
}

//链接
- (void)connectMqtt:(resultCallBack)result{
    
    if(!self.devModel||!self.mqtt_host||!self.mqtt_port){
        return;
    }
    NSLog(@"---->连接mqtt,ip:%@ port:%zd ,userName = %@ ,password = %@",self.mqtt_host,self.mqtt_port,self.devModel.devId,self.devModel.secretKey);
    self.devModel.commandsArray = [NSMutableArray array];
    [self.mySession setUserName:self.devModel.devId];
    [self.mySession setPassword:self.devModel.secretKey];
    [self.mySession setWillQoS:MQTTQosLevelExactlyOnce]; //接收离线消息级别
    [self.mySession setClientId:[NSString stringWithFormat:@"DE%@",self.devModel.devId]];
    self.mySession.transport = self.transport;
    [self.mySession setDelegate:self];
    //[self.mySession connectAndWaitTimeout:1];
    [self.mySession connectWithConnectHandler:^(NSError *error) {
        if(error){
            NSLog(@"----->connect fail:%@",error);
        }
        if(result){
            result(error?NO:YES);
        }
        
       
    }];
}

//断开连接
- (void)disConnectMqtt:(resultCallBack)result{
    if(self.devModel){
        //[self.mySession closeAndWait:1];
        /*[self.mySession closeWithDisconnectHandler:^(NSError *error) {
            if(result){
                result(error?NO:YES);
            }
            self.devModel = nil;
        }];*/
        
        [self.mySession disconnect];
    }
}



- (void)multipleContentMqtt:(NSInteger)count ueseName:(NSString *)name  password:(NSString *)password{
    
    for (NSInteger i = 0; i<count; i++) {
        MQTTCFSocketTransport *transport = [[MQTTCFSocketTransport alloc] init];
        transport.host = _mqtt_host;
        transport.port = _mqtt_port;
        
        MQTTSession *session = [[MQTTSession alloc] init];
        [session setWillQoS:MQTTQosLevelAtMostOnce];
        [session setClientId:[NSString stringWithFormat:@"MQTT_Test_%ld",i+1]];
        [session setSessionExpiryInterval:@60];
        session.transport = transport;
        [session setDelegate:self];
        [self.sessionArray addObject:session];
        
        //[session connectAndWaitTimeout:1];
            
        [RACObserve(self, beginConnect) subscribeNext:^(id  _Nullable x) {
            [session connectAndWaitTimeout:1];
        }];
        
        [RACObserve(self, isSend) subscribeNext:^(id  _Nullable x) {
            //[self sendMsg:session msgContent:[NSString stringWithFormat:@"hello world %ld",i+1]];
        }];
    }
    
//    [self.sessionArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//        MQTTSession *session = obj;
//        [session setDelegate:self];
//        [session connectAndWaitTimeout:1];
//    }];
    
    self.beginConnect = YES;
    
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(timerTest) userInfo:nil repeats:YES];

    // NSDefaultRunLoopMode模式，切换RunLoop模式，定时器停止工作.
    // [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    
    // UITrackingRunLoopMode模式，切换RunLoop模式，定时器停止工作.
    // [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
    
    // common modes的模式,以下三种模式的组合模式 NSDefaultRunLoopMode & NSModalPanelRunLoopMode & NSEventTrackingRunLoopMode
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

}


- (void)timerTest{
    //self.isSend = YES;
}

#pragma mark - MQTTSessionDelegate
- (void)handleEvent:(MQTTSession *)session event:(MQTTSessionEvent)eventCode error:(NSError *)error{
    
    switch (eventCode) {
            case MQTTSessionEventConnected:
                NSLog(@"连接成功");
                [QMUITips showWithText:@"连接成功"];
                self.isConnect = YES;
                self.devModel.isOnline = YES;
                break;
            case MQTTSessionEventConnectionRefused:
                NSLog(@"连接被拒绝");
                [QMUITips showWithText:@"连接被拒绝"];
                self.isConnect = NO;
                self.devModel.isOnline = NO;
                break;
            case MQTTSessionEventConnectionClosed:
                NSLog(@"连接关闭");
                [QMUITips showWithText:@"连接关闭"];
                self.isConnect = NO;
                self.devModel.isOnline = NO;
                break;
            case MQTTSessionEventConnectionError:
                NSLog(@"连接错误");
                [QMUITips showWithText:@"连接错误"];
                self.isConnect = NO;
                self.devModel.isOnline = NO;
                break;
            case MQTTSessionEventProtocolError:
                NSLog(@"协议不被接受/协议错误");
                [QMUITips showWithText:@"协议不被接受/协议错误"];
                self.isConnect = NO;
                self.devModel.isOnline = NO;
                break;
            case MQTTSessionEventConnectionClosedByBroker:
                NSLog(@"其余错误");
                [QMUITips showWithText:@"其余错误"];
                self.isConnect = NO;
                self.devModel.isOnline = NO;
                break;
                
            default:
                break;
        }
}


//接收消息
- (void)newMessage:(MQTTSession *)session
              data:(NSData *)data
           onTopic:(NSString *)topic
               qos:(MQTTQosLevel)qos
          retained:(BOOL)retained
               mid:(unsigned int)mid{
    
    // 进行下一步操作,不一定是字符串
    NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"收到的消息：%@",result);
    
    if([topic isEqualToString:self.devModel.subTopic]){//对比是否是对应主题
        /**
        * 发送MQ给设备
        * @param topic 格式: DE-XXXXXX
        * @param content
        * 格式 {"deviceId":"主设备ID","msgType":"消息类型","sn":"SN","data":{"key1","value1"}}
        * @throws MqttPersistenceException
        * @throws MqttException
        */
        
//        RHMQMsgModel *model = [RHMQMsgModel yy_modelWithJSON:result];
//        if(model){
//            [self.devModel.commandsArray insertObject:model atIndex:0];
//            [[NSNotificationCenter defaultCenter] postNotificationName:DeviecNewMsgNotification object:nil];
//        }
    }
    if([topic isEqualToString:[NSString stringWithFormat:@"DEVICE/MSG/%@",self.devModel.devId]]){
        //判断是否要回复此消息
        NSMutableDictionary *message = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        if([message[@"protocolHead"][@"cmdId"] length] > 0){
            //参数设置消息
            if([message[@"protocolHead"][@"namespace"] isEqualToString:@"M_control"]){
                NSMutableDictionary  *answer_result = [NSMutableDictionary dictionary];
                if(message[@"protocolBody"]){
                    [answer_result addEntriesFromDictionary:message[@"protocolBody"]];
                    [answer_result setObject:@"200" forKey:@"resultCode"];
                    [answer_result setObject:@"操作成功" forKey:@"msg"];
                }
                [message setObject:answer_result forKey:@"protocolBody"];
                
                NSString *answer = [message yy_modelToJSONString];
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    [self sendMessage:answer topicSN:[NSString stringWithFormat:@"SERVER/MSG/%@",self.devModel.devId] handler:^(BOOL isSuccess) {
                        if(isSuccess){
                            NSLog(@"----->回复主题:%@成功 :%@",[NSString stringWithFormat:@"SERVER/MSG/%@",self.devModel.devId],answer);
                        }else{
                            NSLog(@"----->回复主题:%@失败",[NSString stringWithFormat:@"SERVER/MSG/%@",self.devModel.devId]);
                        }
                    }];
                });
                
            }
        
        }
        
        //是否是升级命令
        if([message[@"protocolHead"][@"namespace"] isEqualToString:@"B_upgrade"]){
            NSArray *paraList = message[@"protocolBody"][@"commandParamList"];
            NSMutableDictionary *updateDic = [NSMutableDictionary dictionary];
           
            for (NSDictionary *dic in paraList) {
                if([dic[@"paramName"]isEqualToString:@"sn"]){
                    [updateDic setValue:dic[@"value"] forKey:@"sn"];
                }
                if([dic[@"paramName"]isEqualToString:@"firmwareType"]){
                    [updateDic setValue:dic[@"value"] forKey:@"firmwareType"];
                }
            }
            NSDictionary *para = @{@"deviceId":[RHMQTTManage shareMQTTManage].devModel.devId,
                                   @"password":[RHMQTTManage shareMQTTManage].devModel.secretKey,
                                   @"updateDtoList":@[updateDic]
            };
            
            //获取最新固件列表
            [BaseModel startWithCompletionAPIKey:D_getDownLoadUrl argument:para requestSuccess:^(__kindof BaseRequest *request, ResultModel *resultModel) {
                if(resultModel.code == 200){
                    //是否要回复服务器
                    if([message[@"protocolHead"][@"cmdId"] length] > 0){
                        NSMutableDictionary  *answer_result = [NSMutableDictionary dictionary];
                        if(message[@"protocolBody"]){
                            [answer_result addEntriesFromDictionary:message[@"protocolBody"]];
                            [answer_result setObject:@"200" forKey:@"resultCode"];
                            [answer_result setObject:@"升级成功" forKey:@"msg"];
                        }
                        [message setObject:answer_result forKey:@"protocolBody"];
                        
                        NSString *answer = [message yy_modelToJSONString];
                        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                            [self sendMessage:answer topicSN:[NSString stringWithFormat:@"SERVER/MSG/%@",self.devModel.devId] handler:^(BOOL isSuccess) {
                                if(isSuccess){
                                    NSLog(@"----->回复主题:%@成功 :%@",[NSString stringWithFormat:@"SERVER/MSG/%@",self.devModel.devId],answer);
                                }else{
                                    NSLog(@"----->回复主题:%@失败",[NSString stringWithFormat:@"SERVER/MSG/%@",self.devModel.devId]);
                                }
                            }];
                        });
                        
                    }
                        
                }
                
            } requestFail:^(__kindof BaseRequest *request, ResultModel *resultModel) {
                
            }];
            
            
        }
        
        
        
        NSLog(@"----->收到主题 %@ 的信息%@",[NSString stringWithFormat:@"DEVICE/MSG/%@",self.devModel.devId],result);
        
        
    }
    
    if([topic isEqualToString:[NSString stringWithFormat:@"DEVICE/ERROR/%@",self.devModel.devId]]){
        NSLog(@"----->收到主题 %@ 的错误信息%@",[NSString stringWithFormat:@"DEVICE/MSG/%@",self.devModel.devId],result);
        
    }

}

// MQTT连接成功，进行主题订阅,设置主题服务质量
- (void)connected:(MQTTSession *)session{
    //[session subscribeToTopic:@"d-deviceId" atLevel:MQTTQosLevelAtMostOnce];
    
    [session subscribeToTopic:self.devModel.subTopic atLevel:MQTTQosLevelAtMostOnce];
    [session subscribeToTopic:[NSString stringWithFormat:@"DEVICE/MSG/%@",self.devModel.devId] atLevel:MQTTQosLevelAtMostOnce];
    [session subscribeToTopic:[NSString stringWithFormat:@"DEVICE/ERROR/%@",self.devModel.devId] atLevel:MQTTQosLevelAtMostOnce];
    [[NSNotificationCenter defaultCenter] postNotificationName:DeviecStateChangeNotification object:nil];
    NSLog(@"----->订阅主题:%@, %@",[NSString stringWithFormat:@"DEVICE/MSG/%@",self.devModel.devId],[NSString stringWithFormat:@"DEVICE/ERROR/%@",self.devModel.devId]);
}
 

// MQTT连接关闭，移除订阅主题
- (void)connectionClosed:(MQTTSession *)session{
    [session unsubscribeTopic:self.devModel.subTopic];
    [[NSNotificationCenter defaultCenter] postNotificationName:DeviecStateChangeNotification object:nil];
    
}


//发送消息
/*-(void)sendMsg:(MQTTSession *)session msgContent:(NSString *)content{
    NSString *str = content;
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    [session publishData:data onTopic:@"d-deviceId" retain:NO qos:MQTTQosLevelAtMostOnce publishHandler:^(NSError *error) {
           
           if (error) {
               // 发送失败则 重新登录 mqtt 进行重发
            //   [self getMQTTServerAnew];
               
           }else {
               //主题发送成功
               NSLog(@"主题 %@ 发送成功", @"所订阅的主题mobtopic");
           }
           
       }];
}*/

//发送信息
- (void)sendMessage:(NSString *)msg handler:(resultCallBack)result{
    
    if(!msg||!self.devModel){
        return;
    }
    
    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
    [self.mySession publishData:data onTopic:self.devModel.pubTopic retain:NO qos:MQTTQosLevelAtMostOnce publishHandler:^(NSError *error) {
        if(error){
            NSLog(@"主题 %@ 发送失败", self.devModel.pubTopic);
//            [QMUITips showWithText:[NSString stringWithFormat:@"Topic: %@ \n发送失败",self.devModel.pubTopic]];
        }else{
            NSLog(@"主题 %@ 发送成功", self.devModel.pubTopic);
//            [QMUITips showWithText:[NSString stringWithFormat:@"Topic: %@ \n发送成功",self.devModel.pubTopic]];
        }
        if(result){
            result(error?NO:YES);
        }
    }];
}

//向某一主题发送消息
- (void)sendMessage:(NSString *)msg topicSN:(NSString*)topicSN handler:(resultCallBack)result
{
    if(!msg||!self.devModel){
        return;
    }
    
    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
//    NSString *theme = [NSString stringWithFormat:@"%@/%@",self.devModel.pubTopic,topicSN];
    [self.mySession publishData:data onTopic:topicSN retain:NO qos:MQTTQosLevelAtMostOnce publishHandler:^(NSError *error) {
        if(error){
            NSLog(@"主题 %@ 发送失败", topicSN);
//            [QMUITips showWithText:[NSString stringWithFormat:@"Topic: %@ \n发送失败",self.devModel.pubTopic]];
        }else{
            NSLog(@"主题 %@ 发送成功", topicSN);
//            [QMUITips showWithText:[NSString stringWithFormat:@"Topic: %@ \n发送成功",self.devModel.pubTopic]];
        }
        if(result){
            result(error?NO:YES);
        }
    }];
}
@end
